package com.wxg.demo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.wxg.entity.EleIdAndBounds;
import com.wxg.entity.MyPage;
import com.wxg.entity.MyPages;
import com.wxg.entity.WebEleBounds;
import com.wxg.utils.My;
import com.wxg.utils.MyDriver;
import com.wxg.utils.MyFileReader;
import com.wxg.utils.MyFileWriter;

/**
 * 
 * 1) 首先获得html文件,给block元素标记id,输出到临时文件夹
 * 2) 测试block元素的height
 * 
 * 4) 将跨页的block元素id记录下来
 * 5) 承上，使用Jsoup将所有元素加上span标签,输出到临时文件,将它们拆分;放入String数组中!
 * 6) 替换被标记的block元素!
 * 7) 插入PageHeader,PageFooter, 插入到PageMain, 生成新的文件, 输送到前台！
 * 
 * 1) 暂时不考虑一个block元素包裹另一个block元素的情况(UE中的段落应该都是P元素, P元素内部不会再插入block元素了)
 * 
 * 
 * @author Wxg
 *
 */
public class Emr102 {

	/**
	 * div[class="emr_main"] 的高度
	 */
	public static final int MAIN_HEIGHT = 940;
	
	/**
	 * 暂时未使用
	 * 如果元素的高度小于 MIN_H, 直接输出到下一个页面!( 不拆分这个元素 )
	 */
	public static final int MIN_H = 20;
	
	/**
	 * 添加id后存储到本地的html文件的地址
	 */
	public static String genFilepath;
	
	public static MyPages pages;
	
	public static void main(String[] args) {
//		code104();
//		code102();
//		insertHeaderAndFooter();
		
		code105();
	}
	
	
	public static void code105(){
		String dirpath = "F:\\wxg\\for_print\\myjfserver\\src\\main\\webapp\\uehtml";
		// 附加id属性,并存储html到本地磁盘
		storeHtmlWithGenId( dirpath + "\\html_102.html" );
		
		String url = My.fileUrl( genFilepath );
		List<EleIdAndBounds> list = whosOverPage(url);
		
		if(null != list){
			for(EleIdAndBounds ib : list){
				System.out.println( ib );
			}
		}
		
		// insertHeaderAndFooter( outerHtmlList );
		insertHeaderAndFooter();
	}
	
	
	/**
	 * 这段代码留下, 从中可以看到曾经犯下的错误！
	 * 1) Jsoup.parse(File genFilepath, "UTF-8");
	 * -	* 如果传入String参数,parse方法会将其理解为一个html片段
	 * 2) @see com.wxg.utils.MyFileWriter 的成员属性 `wrtier` 不应该定义为static
	 * 
	 */
	public static void code104(){
		String dirpath = "F:\\wxg\\for_print\\myjfserver\\src\\main\\webapp\\uehtml";
		// 附加id属性,并存储html到本地磁盘
		storeHtmlWithGenId( dirpath + "\\html_102.html" );
		
		String url = My.fileUrl( genFilepath );
		List<EleIdAndBounds> list = whosOverPage(url);
		if(null != list){
			for(EleIdAndBounds ib : list){
				System.out.println( ib );
			}
		}
		
//		if(null != pages){
//			for(MyPage page : pages.getPages()){
//				if(null != page){
//					for(String id : page.getIds()){
//						System.out.println( id );
//					}
//				}
//			}
//		}
		
		List<String> outerHtmlList = new ArrayList<String>();
		
		/**
		 * 写法有问题: Jsoup.parse(String genFilepath);
		 * 应该是: Jsoup.parse(File genFilepath, "UTF-8");
<html>
 <head></head>
 <body>
  D:\wxg\downloadStore\20180207_1108001.html
 </body>
</html>
		 */
		Document doc = null;
		try {
			doc = Jsoup.parse(new File(genFilepath), "UTF-8");
//			System.out.println("========");
//			System.out.println( doc );
			for(MyPage page : pages.getPages()){
				for(String id : page.getIds()){
					// 有问题. 这里出现空指针
					outerHtmlList.add( doc.getElementById(id).outerHtml() );
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//
		insertHeaderAndFooter( outerHtmlList );
		
	}
	
	
	
	/**
	 * 1) 首先获得html文件,给block元素标记id,输出到临时文件夹
	 * @see com.wxg.demo.HowManyBlockTags
	 * @see com.wxg.demo.jsoup.JsoupDemo101
	 * 
	 * body也是block元素,但是不添加id标记( 使用的是"getAllElements()" )
	 * 
	 */
	public static void code101(){
		String dirpath = "F:\\wxg\\for_print\\myjfserver\\src\\main\\webapp\\uehtml";
		
		storeHtmlWithGenId( dirpath + "\\html_101.html" );
		
		// 得到保存的文件名路径及地址
		System.out.println( genFilepath );
	}
	
	/**
	 * 添加id属性,存储文件,保存文件地址
	 * 
	 * @param sourceFilepath
	 */
	public static void storeHtmlWithGenId(String sourceFilepath){
		File file = new File( sourceFilepath );
		Document doc = null;
		try {
			doc = Jsoup.parse(file, "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		Element body = doc.body();
		Elements eles = body.getAllElements();
		int id = 1;
		for(Element ele : eles){
			if(!"body".equalsIgnoreCase(ele.tagName())){
				if(ele.isBlock()){
					ele.attr("id", "id_"+(id++));
				}
			}
		}
		
		MyFileWriter myw = new MyFileWriter();
		myw.writeb( doc.toString() );
		myw.close();
		genFilepath = myw.getFilepath();
	}
	
	/**
	 * 2) 测试block元素的height
	 * 因为给所有的block元素添加了"id_"的id属性,所以查找会很方便
	 * By.xpath("//*[starts-with(@id,'id_')]")
	 * 
	 */
	public static void code102(){
		
		String filepath = "D:\\wxg\\downloadStore\\20180206_2012001.html";
		String url = My.fileUrl(filepath);
		
		Map<String, WebEleBounds> map = getBlockEleBounds( url );
		if(null != map){
			System.out.println( map );
		}
	}
	
	/**
	 * 4) 将跨页的block元素id记录下来
	 * 
	 */
	public static void code103(){
		String filepath = "D:\\wxg\\downloadStore\\20180206_2012001.html";
		String url = My.fileUrl(filepath);
		List<EleIdAndBounds> list = whoIsOverPage(url);
		if(null != list){
			for(EleIdAndBounds ib : list){
				System.out.println( ib );
			}
		}
	}
	
	
	/**
	 * @see com.wxg.demo.HowManyBlockTags
	 * tbody, tr, td 要去除, 它们是一个整体,属于 table
	 * 
	 * update : table, tr 筛选出来
	 * 
	 * @param url
	 * @return
	 */
	@Deprecated
	public static Map<String, WebEleBounds> getBlockEleBounds(String url) {
		// 存储block元素的id和height; 或者Map<WebElement, Integer>,但是driver quit后也许会失效
		// Map<String, Integer> map = new HashMap<String, Integer>();
		Map<String, WebEleBounds> map = new LinkedHashMap<String, WebEleBounds>();

		WebDriver driver = MyDriver.getStaticDriver();
		driver.get( url );
		List<WebElement> list = driver.findElements(By.xpath("//*[starts-with(@id,'id_')]"));

		String[] exceptArr = {"tbody", "tr", "td"}; //{"tbody", "td"}; //{"tbody", "tr", "td"};
		
		if (null != list) {
			for (WebElement ele : list) {
				if(My.notIn(ele.getTagName(), exceptArr)){
					Dimension d = ele.getSize();
					Point p = ele.getLocation();
					WebEleBounds bounds = new WebEleBounds(p.x, p.y, d.width, d.height);
					map.put(ele.getAttribute("id"), bounds);
				}
			}
		}

		// webdriver quit
		MyDriver.closeStaticDriver();
		
		return map;
	}
	
	/**
	 * @see com.wxg.demo.HowManyBlockTags
	 * tbody, tr, td 要去除, 它们是一个整体,属于 table
	 * 
	 * update : table, tr 筛选出来
	 * 
	 * 替代 getBlockEleBounds
	 * 
	 * @param url
	 * @return
	 */
	public static List<EleIdAndBounds> getBlockElement(String url){
		List<EleIdAndBounds> retList = new ArrayList<EleIdAndBounds>();

		WebDriver driver = MyDriver.getStaticDriver();
		driver.get( url );
		List<WebElement> list = driver.findElements(By.xpath("//*[starts-with(@id,'id_')]"));

		String[] exceptArr = {"tbody", "tr", "td"};
		
		if (null != list) {
			for (WebElement ele : list) {
				if(My.notIn(ele.getTagName(), exceptArr)){
					Dimension d = ele.getSize();
					Point p = ele.getLocation();
					WebEleBounds bounds = new WebEleBounds(p.x, p.y, d.width, d.height);
					retList.add( new EleIdAndBounds(ele.getAttribute("id"), bounds) );
				}
			}
		}

		// webdriver quit
		MyDriver.closeStaticDriver();
		
		return retList;
	}
	
	/**
	 * 得出跨页的元素
	 * 
	 * @param url
	 * @return
	 */
	@Deprecated
	public static List<EleIdAndBounds> whoIsOverPage(String url){
		List<EleIdAndBounds> list = new ArrayList<EleIdAndBounds>();
		List<EleIdAndBounds> ibList = getBlockElement(url);
		int len = ibList.size();
		
		int height = 0;
		for(int i=0; i<len; i++){
			EleIdAndBounds ib = ibList.get(i);
			height += ib.bounds.height;
			if( height > MAIN_HEIGHT ){
				// if( ib.bounds.height <= MIN_H ){  } // 不添加到list中!
				list.add( ibList.get(i-1) ); // 上一个元素
				height = ib.bounds.height; // 重新开始计算
			}
		}
System.out.println( height );
		return list;
	}
	
	/**
	 * 代替 whoIsOverPage
	 * 
	 * 使用 (bounds.y+height) 来计算元素的位置(高度), 再与"MAIN_HEIGHT"进行比较
	 * 
	 * 问题:
	 * 1) 跨页的元素, 多少放在上一页, 多少放在下一页呢?
	 * 2) table 要按照tr来计算才准确啊: 以便于将其切割
	 * 
	 * 
	 * @param url
	 * @return
	 */
	public static List<EleIdAndBounds> whosOverPage(String url){
		List<EleIdAndBounds> list = new ArrayList<EleIdAndBounds>();
		
		
		List<EleIdAndBounds> ibList = getBlockElement(url);
//		int len = ibList.size();
//		int height = 0;
//		for(int i=0; i<len; i++){
//			
//		}
		int currentPage = 1;
		pages = new MyPages();
		MyPage page = pages.newPage();
		for(EleIdAndBounds ib : ibList){
			if( (ib.bounds.y + ib.bounds.height - MAIN_HEIGHT*(currentPage-1)) > MAIN_HEIGHT ){
				list.add(ib);
				currentPage++;
				page = pages.newPage();
			}
			page.add(ib.id);
		}
		
		return list;
	}
	
	/**
	 * 插入pageHeader,pageFooter
	 * @see com.wxg.demo.Emr101
	 * 
	 */
	@Deprecated
	public static void insertHeaderAndFooter(List<String> outerHtmlList){
		
		// writer
		String dir = My.conf("htmlStoreDir");
		String filepath = dir + My.SP + My.ss("html_") + ".html";
		System.out.println( "===filepath===" );
		System.out.println( filepath );
		MyFileWriter writer = new MyFileWriter(filepath);
		
		writer.writeb("<html>");
		
		// head
		MyFileReader mfr = new MyFileReader("com/wxg/html/a102/head.html");
		for(String str : mfr.list()){
			writer.writeb(str);
		}
		// body
		writer.writeb("<body>");
		// page_header
		mfr = new MyFileReader("com/wxg/html/a102/pageHeader.html");
		for(String str : mfr.list()){
			writer.writeb(str);
		}
		
		// main
		writer.writeb("<h1>Hello,World!</h1>");
//		Document doc = Jsoup.parse(genFilepath);
//		for(MyPage page : pages.getPages()){
//			for(String id : page.getIds()){
//				writer.writeb( doc.getElementById(id).outerHtml() );
//			}
//		}
		
		for(String str : outerHtmlList){
			writer.writeb( str );
		}
		
		
		// page_footer
		mfr = new MyFileReader("com/wxg/html/a102/pageFooter.html");
		for(String str : mfr.list()){
			writer.writeb(str);
		}
		
		writer.writeb("</body>");
		
		writer.writeb("</html>");
		
		// writer close
		writer.close();
		System.out.println( filepath );
	}
	
	/**
	 * 插入pageHeader,pageFooter
	 * @see com.wxg.demo.Emr101
	 * 
	 * 
	 */
	public static void insertHeaderAndFooter(){
		
		Document doc = null;
		try {
			doc = Jsoup.parse(new File(genFilepath), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// writer
		String dir = My.conf("htmlStoreDir");
		String filepath = dir + My.SP + My.ss("html_") + ".html";
		
		MyFileWriter writer = new MyFileWriter(filepath);
		
		writer.writeb("<html>");
		
		// head
		writer.writeb("<head>");
		
		// 提取原html中的head内容
		if(null != doc){
			Element head = doc.getElementsByTag("head").get(0);
			for(Element ele : head.children()){
				writer.writeb( ele.outerHtml() );
			}
		}
		
		//加入自己的style(放在后面)
		MyFileReader mfr = new MyFileReader("com/wxg/html/a102/mystyle.html");
		for(String str : mfr.list()){
			writer.writeb(str);
		}
		writer.writeb("</head>");
		// body
		writer.writeb("<body>");
		
		if(null != doc){
			int i = 1; // 页码
			for(MyPage page : pages.getPages()){
				// page_header : 要放到page循环中
				mfr = new MyFileReader("com/wxg/html/a102/pageHeader.html");
				for(String str : mfr.list()){
					writer.writeb(str);
				}
				
				for(String id : page.getIds()){
					writer.writeb( doc.getElementById(id).outerHtml() );
				}
				
				// page_footer : 要放到page循环中
				mfr = new MyFileReader("com/wxg/html/a102/pageFooter.html");
				for(String str : mfr.list()){
					if(str.contains("{{page}}")){
						str = str.replace("{{page}}", i+"");
					}
					writer.writeb(str);
				}
				i++;
			}
		}
		
		writer.writeb("</body>");
		
		writer.writeb("</html>");
		
		// writer close
		writer.close();
		System.out.println( filepath );
	}
	
	
	
}
